#ifndef _UTILEX_TIMETHREAD_HPP_
#define _UTILEX_TIMETHREAD_HPP_

#include <crt_util.h>
#include <utilex/cond.hpp>
#include <utilex/sem.hpp>

#ifdef __cplusplus

class CTimeThread
{
public:
	CTimeThread() {
		m_Exit = 0;
		m_sec = 0;
		thread = INVALID_HANDLE_VALUE;
		m_State = S_ERROR;
	}
	virtual ~CTimeThread() {

	
	}

	HRESULT SetMilliSecond(int ms) {
		m_sec = ms;
		return S_OK;
	}
	int PostSingel() {
		m_CondPost.Signal();
		return S_SUCCESS;
	}

	int PostBroadcast() {
		m_CondPost.Broadcast();
		return S_SUCCESS;
	}

	UINT SetState(UINT state) {

		m_State = state;
		return m_State;
	}

	UINT GetState() {

		return m_State;
	}

public:

	static void time_thread_proc(void* pthis) {
		CTimeThread* p = static_cast<CTimeThread*>(pthis);
		if (p) {
			p->Post();
			p->Time_Thread_Run_Proc();
			p->Post();
		}
		else {
			p->Post();
		}
	}



	int Start_Tm_Thread() {

		int rc = _thread_create(&thread, CTimeThread::time_thread_proc, this);
		rc_assert(rc == S_SUCCESS, S_ERROR)
		this->Wait();
		return S_SUCCESS;

	}

	int Stop_Tm_Thread() {

		rc_assert(thread != INVALID_HANDLE_VALUE, S_ERROR)

		Exit_Thread();
		PostBroadcast();

		if (this->GetState() != S_SUCCESS)
			this->Wait();

		_thread_join(&thread);
		return S_SUCCESS;

	}
protected:
	HRESULT Time_Thread_Run_Proc() {
		
		while (!m_Exit)
		{
			logi("Time_Thread_Run_Proc stop");
			this->m_CondPost.WaitTime(m_sec);
			//this->m_CondPost.Wait();

			rc_assert_break(m_Exit == 0)
			this->Time_Thread_Run();
			logi("Time_Thread_Run_Proc end");
		}
		return S_OK;
	}
private:
	HRESULT Post() {

		m_Sem.Post();
		return S_OK;
	}

	HRESULT Wait() {

		rc_assert(thread != INVALID_HANDLE_VALUE, S_ERROR)
		m_Sem.Wait();
		return S_SUCCESS;
	}

	HRESULT Exit_Thread() {

		SYNC_OBJ(&m_csLock);
		m_Exit = 1;
		return S_OK;
	}
protected:
	std_method(Time_Thread_Run)() PURE;
protected:
	_thread_t		thread;
	CAutoLock		m_csLock;
	CCondHandle		m_CondPost;
	CSemHandle		m_Sem;
	UINT			m_Exit;
	int				m_sec;
	UINT			m_State;
};

#endif


#endif
